package tech.mhuang.pacebox.core.page;

import tech.mhuang.pacebox.core.util.CollectionUtil;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 内存分页工具类
 *
 * @author mhuang
 * @since 1.1.2
 */
public class PageUtil {
    /**
     * subList分页
     *
     * @param dataList      需要分页的数据
     * @param pageParamList 分页的条件
     * @param <T>           类型
     * @return 分页结果
     */
    public static <T> List<List<T>> subList(List<T> dataList, List<PageParam> pageParamList) {
        int size = dataList.size();
        //倒序排序并且判断如果数量满足则取对应的分页条件
        Optional<PageParam> first = pageParamList.stream().sorted(Comparator.comparing(PageParam::getMax).reversed()).filter(page -> size >= page.getMax()).findFirst();

        PageParam subPage = first.orElse(PageParam.init(size));
        int page, num;
        //数量 根据总数除以数量得到批次
        if (subPage.getType() == 1) {
            num = subPage.getNum();
            page = size / num;
            if (size % num != 0) {
                page = page + 1;
            }
        } else {
            //批次数 根据总数除以批次量得到数量
            page = subPage.getNum();
            num = size / page;
            if (size % page != 0) {
                num = num + 1;
            }
        }
        List<List<T>> resultList = CollectionUtil.capacity(ArrayList.class, page);
        //因为从零开始所以不用等于page
        for (int start = 0; start < page; start++) {
            resultList.add(subList(dataList, start, num));
        }
        return resultList;
    }

    public static <T> List<T> subList(List<T> dataList, int page, int num) {
        return dataList.stream().skip(page * num).limit(num).collect(Collectors.toList());
    }

    /**
     * 总页数
     *
     * @param total    总数
     * @param pageSize 每页数
     * @return 页数
     * @since 1.1.6
     */
    public static int totalPage(int total, int pageSize) {
        return totalPage((long) total, pageSize);
    }

    public static int totalPage(long totalCount, int pageSize) {
        if (pageSize == 0) {
            return 0;
        }
        return Math.toIntExact(totalCount % pageSize == 0 ? (totalCount / pageSize) : (totalCount / pageSize + 1));
    }

    /**
     * 分页彩虹算法
     * 来自：<a href="https://github.com/iceroot/iceroot/blob/master/src/main/java/com/icexxx/util/IceUtil.java">
     * https://github.com/iceroot/iceroot/blob/master/src/main/java/com/icexxx/util/IceUtil.java</a><br>
     *
     * @param currentPage  当前页
     * @param pageCount    总页数
     * @param displayCount 每屏展示的页数
     * @return 分页条
     * @since 1.1.6
     */
    public static int[] rainbow(int currentPage, int pageCount, int displayCount) {
        boolean isEven = displayCount % 2 == 0;
        int left = displayCount / 2;
        int right = displayCount / 2;

        int length = displayCount;
        if (isEven) {
            right++;
        }
        if (pageCount < displayCount) {
            length = pageCount;
        }
        int[] result = new int[length];
        if (pageCount >= displayCount) {
            if (currentPage <= left) {
                for (int i = 0; i < result.length; i++) {
                    result[i] = i + 1;
                }
            } else if (currentPage > pageCount - right) {
                for (int i = 0; i < result.length; i++) {
                    result[i] = i + pageCount - displayCount + 1;
                }
            } else {
                for (int i = 0; i < result.length; i++) {
                    result[i] = i + currentPage - left + (isEven ? 1 : 0);
                }
            }
        } else {
            for (int i = 0; i < result.length; i++) {
                result[i] = i + 1;
            }
        }
        return result;

    }

    /**
     * 分页彩虹算法(默认展示10页)<br>
     * 来自：<a href="https://github.com/iceroot/iceroot/blob/master/src/main/java/com/icexxx/util/IceUtil.java">
     *     https://github.com/iceroot/iceroot/blob/master/src/main/java/com/icexxx/util/IceUtil.java</a>
     *
     * @param currentPage 当前页
     * @param pageCount   总页数
     * @return 分页条
     * @since 1.1.6
     */
    public static int[] rainbow(int currentPage, int pageCount) {
        return rainbow(currentPage, pageCount, 10);
    }
}
